#pragma once
#include "noncopyable.h"
#include "InetAddress.h"
#include "EventLoop.h"
#include "Logger.h"
#include "EventLoopThreadPool.h"
#include "Acceptor.h"
#include "Callbacks.h"
#include "TcpConnection.h"
#include "Buffer.h"
#include "Timestamp.h"
#include "Channel.h"
#include "EventLoopThread.h"
#include "Poller.h"
#include "EpollPoller.h"
#include "Thread.h"

#include <memory>
#include <unordered_map>

class TcpServer : Noncopyable
{
public:
    using ThreadInitCallback = std::function<void(EventLoop *)>;

    enum Option
    {
        kNoReusePort,
        KReusePort
    };

    TcpServer(EventLoop *loop, const InetAddress &listenAddr, const std::string& name, Option option = kNoReusePort);
    ~TcpServer();

    void setConnectionCallback(const ConnectionCallback &cb) { connectionCallback_ = cb; }
    void setCloseCallback(const CloseCallback &cb) { closeCallback_ = cb; }
    void setWriteCompleteCallback(const WriteCompleteCallback &cb) { writeCompleteCallback_ = cb; }
    void setMessageCallback(const MessageCallback &cb) { messageCallback_ = cb; }

    void setThreadNum(int numThreads); // 设置subloop数量

    void start(); // 开启监听

private:
    void newConnection(int sockfd, const InetAddress &peerAddr);
    void removeConnection(const TcpConnectionPtr &conn);
    void removeConnectionInLoop(const TcpConnectionPtr &conn);

    using ConnectionMap = std::unordered_map<std::string, TcpConnectionPtr>;

    EventLoop *loop_; // baseloop(mainloop)

    const std::string ipPort_;
    const std::string name_;

    std::unique_ptr<Acceptor> acceptor_;             // 运行在mainloop，用于调度线程
    std::shared_ptr<EvenLoopThreadPool> threadPool_; // 对应的线程池 one loop per thread

    ConnectionCallback connectionCallback_;
    CloseCallback closeCallback_;
    WriteCompleteCallback writeCompleteCallback_;
    MessageCallback messageCallback_;


    // 分发事件，在有新线程来的时候回调时候使用
    ThreadInitCallback threadInitCallback_;

    std::atomic_int started_;

    int nextConnId_;
    ConnectionMap connections_; // 保存所有连接
};